<?php

namespace App\Services\ApplyProductOrderRefund;

use App\Models\Order;
use App\Models\OrderItem;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Builder;

class ApplyProductOrderRefund
{
	/**
	 * @var OrderItem
	 */
	protected $item;
	
	/**
	 * @var Order
	 */
	protected $order;
	
	protected $type;
	
	protected $reason;
	
	protected $parcelStatus;
	
	protected $refundMoney;
	
	protected $negoContent;
	
	protected $proofImages = [];
	
	public function __construct(
		OrderItem $item,
		$type,
		$reason,
		$parcelStatus,
		$refundMoney,
		$negoContent = null,
		$proofImages = null)
	{
		$this->item = $item;
		$this->order = $item->order;
		$this->type = $type;
		$this->reason = $reason;
		$this->parcelStatus = $parcelStatus;
		$this->refundMoney = $refundMoney;
		$this->negoContent = $negoContent;
		$this->proofImages = $proofImages;
	}
	
	protected function getExisting(OrderItem $item)
	{
		return $item->order->user->orderRefunds()
			->where('order_id', $item->order->id)
			->where('order_item_id', $item->id)
			->where(function (Builder $query) {
				$query->where('refund_status', 'pending')
					->orWhere('refund_status', 'applied')
					->orWhere('refund_status', 'processing')
					->orWhere('refund_status', 'succeeded');
			})->first();
	}
	
	protected function create()
	{
		return DB::transaction(function () {
			
			$user = $this->item->order->user;
			
			$type = request('type');
			$reason = request('reason');
			$parcelStatus = request('parcel_status');
			$refundMoney = request('refund_money');
			$negoContent = request('nego_content');
			$proofImages = request('proof_images');
			
			$refund = $this->getExisting($this->item);
			
			if (! $refund) {
				$refund = $user->orderRefunds()->create([
					'order_id' => $this->item->order->id,
					'order_item_id' => $this->item->id,
					'type' => $type,
					'reason' => $reason,
					'refund_money' => $refundMoney,
					'parcel_status' => $parcelStatus,
					'proof_images' => $proofImages,
					'refund_status' => 'applied',
				]);
			}
			
			if ($negoContent) {
				$status = $refund->refund_status;
				if ($status !== 'succeeded' and $status !== 'failed') {
					$refund->orderRefundNegos()->create(['content' => $negoContent]);
				}
			}
			
			return $refund;
		});
	}
	
	public function apply()
	{
		return $this->create();
	}
}
